
/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "ui3D场景视口.h"
#include <几何图形/图形相交.h>
#include <节点编辑.h>

#include "物体编辑/3D控制手柄.h"
#include "物体编辑/物体编辑.h"
#include "../节点视口/节点类型构建/物体节点构建.h"
#include "../ui节点视口.h"




//static C_状态条*						g3D视口主状态条 = nullptr;
static std::vector<S_编辑物体更新节点>	g当前拾取节点更新方式;
static vec2 g选框起点坐标;
static vec2 g选框终点坐标;
static bool g打开框选 = false;

bool  C_3D场景视口::g视口摄像机旋转 = false;
bool  C_3D场景视口::g鼠标左键是否按下 = false;
uint8 C_3D场景视口::g视口摄像机平移 = 0;

uint8 C_3D场景视口::g_移动视口_鼠标左键 = 1;
uint8 C_3D场景视口::g_移动视口_键盘按键 = 2;
uint8 C_3D场景视口::g_移动视口_鼠标中键 = 4;


std::vector<C_Widget*> C_3D场景视口::gui_3D视口;




static void f_vecw3d_骨骼编辑模式(S_Props& prop) {
	switch (f_prop_enum(S_节点数据状态::g_骨骼编辑模式)) {
	case 0:
		f_prop_Bool(S_节点数据状态::g_打开编辑模式) = false;
		break;
	
	default:
		f_prop_Bool(S_节点数据状态::g_打开编辑模式) = true;
		break;
	}

	f_OE_骨骼编辑模式切换(S_节点数据状态::g_骨骼编辑模式);
	//if (S_节点数据状态::g_骨骼编辑模式.m_UI->m_Set) S_节点数据状态::g_骨骼编辑模式.m_UI->m_Set(S_节点数据状态::g_骨骼编辑模式);

}




static void on_3D视口布局(C_Widget* self, C_Widget** ws, uint32 num) {
	ws[0]->f_setSize(self->m_Size);
	
	auto e = ws[0]->f_get更新部件();
	for (uint32 i = 0; i < e.m_Num; ++i) {
		e.m_W[i]->f_setSize(self->m_Size);
	}
	
}

static void on_视口操作图形层绘制(C_Widget* self, S_2D画布* 画布) {
	C_3D场景视口* view = static_cast<C_3D场景视口*>(self->m_父部件->m_父部件);
	view->m_旋转缩放线绘制.m_属性 = f_vg_gen属性(画布);

	S_凸边图元 图元 = {};
	图元 = {};
	图元.属性 = f_vg_get属性指针(画布, view->m_背景绘制.m_属性);
	view->m_背景绘制.f_Draw(画布, 图元, E_笔刷类型::e_单色填充);

	图元 = {};
	图元.属性 = f_vg_get属性指针(画布, view->m_背景绘制.m_属性);
	view->m_旋转缩放线绘制.f_Draw(画布, 图元, E_笔刷类型::e_单色描边);

	
	//view->m_背景线绘制.f_Draw(画布, 图元, E_笔刷类型::e_单色描边);
}

static void on_视口操作图形层变换(C_Widget* self) {
	C_3D场景视口* view = (C_3D场景视口*)self->m_父部件;
}

static bool on_Widget鼠标进入(C_Widget* self, const S_鼠标& 鼠标) {
	S_节点数据::g_当前操作视口相机 = f_ui_get3D视口摄像机(self);
	return true;
}


static void on_3D视口物体显示模式(S_Props& prop) {
	E_物体显示模式 模式 = E_物体显示模式(f_prop_enum(prop));
	f_NodeCtx_物体显示模型(模式);

	if (prop.m_UI->m_部件) {
		C_工作区页面* page = static_cast<C_工作区页面*>(prop.m_UI->m_部件->m_父部件->m_父部件->m_父部件);
		static_cast<C_3D场景视口*>(page->mui_画布页面)->f_设置渲染方式(模式);
	}
	
}

static void on_3D视口场景物体显示方式(S_Props& prop) {

}


static void on_3D场景视口_渲染场景(C_Widget* self) {
	C_3D场景视口* view = (C_3D场景视口*)self->m_父部件;
	
	auto camera = f_ui_get3D视口摄像机(view->ui_三维视口);
	vec3 相机位置 = f_camera_get眼睛位置(camera) - S_框架::g_变换手柄->f_get位置();
	//float32 dis = f_get相机到视点距离(f_ui_get3D视口摄像机(view->ui_三维视口)) * 0.075;
	float32 dis = fabs(vec_len(相机位置)) * 0.075;
	f_ob_set缩放(S_框架::g_变换手柄, { dis, dis, dis });

	camera->m_近远端.x = DEF_Max(dis * 0.5, 0.01);



	dis = vec_len(相机位置);
	auto 网格属性 = MeshProp_Init();
	网格属性.m_Remote = (1 - DEF_Min(dis, 500) / 500);
	f_mesh_set间接绘制网格属性(f_ob_fromMesh(S_框架::g_基准网格线, 2), 网格属性);


}


static E_事件是否传递 on_3D视口准备_拖动(C_Widget* self, const S_鼠标& 鼠标, S_拖放数据& data) {
	C_3D场景视口* view = static_cast<C_3D场景视口*>(self->m_父部件->m_父部件);
	
	if (!C_3D场景视口::g视口摄像机旋转 && C_3D场景视口::g视口摄像机平移 <= 1 && S_框架::g_变换轴 == E_轴向::e_None轴向) {
		g选框起点坐标 = f_widget_get鼠标局部位置(C_Widget::g_鼠标.gPos, self);
		g选框终点坐标 = g选框起点坐标;

		view->m_背景绘制.f_alloc(1);
		view->m_旋转缩放线绘制.f_alloc(1);

		g打开框选 = true;
	}
	return E_事件是否传递::e_事件传递_继续;
}

static E_事件是否传递 on_3D视口_拖动(C_Widget* self, const S_鼠标& 鼠标, S_拖放数据& data) {
	C_3D场景视口* view = static_cast<C_3D场景视口*>(self->m_父部件->m_父部件);

	if (g打开框选 && !C_3D场景视口::g视口摄像机旋转 && C_3D场景视口::g视口摄像机平移 <= 1 && S_框架::g_变换轴 == E_轴向::e_None轴向) {
		g选框终点坐标 = f_widget_get鼠标局部位置(C_Widget::g_鼠标.gPos, self);
		
		mat3X2 mat;
		mat.row0 = g选框起点坐标;
		mat.row1 = g选框终点坐标 - mat.row0;
		mat.row2 = { 1,0 };
		view->m_背景绘制.f_set单色填充(0, mat, S_主题颜色::uic_选框面颜色, S_Widget预设图元::m_圆角矩形);

		S_LineProp 线属性 = {0, f_PackData4X8({ 120, 120, 200, 200 }), f_PackData4X8({ 120, 120, 200, 200 }) };
		view->m_旋转缩放线绘制.f_set单色线(0, mat, 线属性, S_Widget预设图元::m_圆角矩形, 1);
	}

	return E_事件是否传递::e_事件传递_继续;
}

static bool on_3D视口_结束拖放(C_Widget* self, C_Widget* 拾取的部件, S_拖放数据& data) {
	C_3D场景视口* view = static_cast<C_3D场景视口*>(self->m_父部件->m_父部件);
	view->m_背景绘制.f_Close();
	view->m_旋转缩放线绘制.f_Close();

	uint8 摄像机平移 = C_3D场景视口::g_移动视口_鼠标左键;
	//摄像机平移 = C_3D场景视口::g_移动视口_键盘按键;
	//摄像机平移 |= C_3D场景视口::g_移动视口_鼠标中键;

	uint8 m = C_3D场景视口::g视口摄像机平移 == 摄像机平移;
	if (!C_3D场景视口::g视口摄像机旋转 && (m) && S_框架::g_变换轴 == E_轴向::e_None轴向) {
		
		auto posA = vec_Min(g选框起点坐标, g选框终点坐标);
		auto posB = vec_Max(g选框起点坐标, g选框终点坐标);
		
		auto size = posB - posA;
		if (size.x > 2 || size.y > 2) {
			auto camera = f_ui_get3D视口摄像机(view->ui_三维视口);
			auto rect = f_ui_get视口(view->ui_三维视口);
			f_view3d_设置激活物体焦点(false);

			vec3 射线[4][2] = { {} };
			//vec3 眼睛位置 = f_camera_get眼睛位置(camera);
			vec3 坐标 = { posA.x, posA.y, 0.00001f };
			射线[0][1] = f_UpProject还原空间顶点(坐标, camera->m_相机投影, (float32*)&(camera->m_相机位置矩阵), rect);
			坐标.z = 1.0;
			射线[0][0] = f_UpProject还原空间顶点(坐标, camera->m_相机投影, (float32*)&(camera->m_相机位置矩阵), rect);

			坐标 = { posB.x, posA.y, 0.00001f };
			射线[1][1] = f_UpProject还原空间顶点(坐标, camera->m_相机投影, (float32*)&(camera->m_相机位置矩阵), rect);
			坐标.z = 1.0;
			射线[1][0] = f_UpProject还原空间顶点(坐标, camera->m_相机投影, (float32*)&(camera->m_相机位置矩阵), rect);

			坐标 = { posB.x, posB.y, 0.00001f };
			射线[2][1] = f_UpProject还原空间顶点(坐标, camera->m_相机投影, (float32*)&camera->m_相机位置矩阵, rect);
			坐标.z = 1.0;
			射线[2][0] = f_UpProject还原空间顶点(坐标, camera->m_相机投影, (float32*)&camera->m_相机位置矩阵, rect);

			//坐标 = { posA.x, posB.y, 0.00001f };
			//射线[3][1] = f_UpProject还原空间顶点(坐标, camera->m_相机投影, (float32*)&camera->m_相机位置矩阵, rect);
			//坐标.z = 1.0;
			//射线[3][0] = f_UpProject还原空间顶点(坐标, camera->m_相机投影, (float32*)&camera->m_相机位置矩阵, rect);


			vec3 三角形[3] = { 射线[0][0], 射线[0][1], 射线[1][1] };
			vec4 plane上 = f_graph_顶点构建平面(三角形);

			三角形[0] = 射线[2][0];
			三角形[1] = 射线[2][1];
			三角形[2] = 射线[2][1] + (射线[0][1] - 射线[1][1]);
			vec4 plane下 = f_graph_顶点构建平面(三角形);

			三角形[0] = 射线[1][0];
			三角形[2] = 射线[1][1];
			三角形[1] = 射线[1][1] + (射线[1][1] - 射线[2][1]);
			vec4 plane右 = f_graph_顶点构建平面(三角形);

			三角形[0] = 射线[0][0];
			三角形[1] = 射线[0][1];
			三角形[2] = 射线[0][1] + (射线[1][1] - 射线[2][1]);
			vec4 plane左 = f_graph_顶点构建平面(三角形);

			三角形[0] = 射线[0][0];
			三角形[1] = 射线[1][0];
			三角形[2] = 射线[2][0];
			vec4 plane近 = f_graph_顶点构建平面(三角形);


			vec4 plane[5] = { plane上, plane下, plane左, plane右, plane近 };

			S_节点数据::g_选中激活物体.clear();
			auto& obs = f_NodeCtx_get默认场景()->m_物体set;
			for (auto* ob : obs) {
				//float32 d上 = f_graph_点到平面距离(f_ob_get全局坐标(ob, ob->m_实例ID), plane上);
				//float32 d下 = f_graph_点到平面距离(f_ob_get全局坐标(ob, ob->m_实例ID), plane下);
				//
				//float32 d左 = f_graph_点到平面距离(f_ob_get全局坐标(ob, ob->m_实例ID), plane左);
				//float32 d右 = f_graph_点到平面距离(f_ob_get全局坐标(ob, ob->m_实例ID), plane右);
				//
				//float32 d近 = f_graph_点到平面距离(f_ob_get全局坐标(ob, ob->m_实例ID), plane近);


				//auto* me = f_ob_fromMesh(ob);
				//if (me && f_surface_框选线框(me, f_ob_get变换矩阵(ob), plane)) {
				//	S_框架::g_选中激活物体.push_back(ob);
				//}
				f_scene_框选物体(ob, S_节点数据::g_选中激活物体, plane);
			}
			f_view3d_设置激活物体焦点(true);

			f_camera_set偏移视点(camera, f_global_get激活物体中心点());
			f_global_变换手柄到物体中心();
		}
	}

	//S_框架::g_变换开关 = false;
	g打开框选 = false;
	S_框架::g_变换轴 = E_轴向::e_None轴向;
	return E_事件是否传递::e_事件传递_继续;
}




C_3D场景视口::C_3D场景视口(S_UI创建环境& ctx) {
	ui_三维视口 = f_ui_创建3D视口(S_框架::g_Scene, { 256,256 }, ctx, *S_框架::g_3D视口环境);
	ctx.m_3DViewScene.push_back(ui_三维视口);
	S_框架::g_视口相机.insert(f_ui_get3D视口摄像机(ui_三维视口));

	ui_操作图形层 = new C_Widget(&ctx);
	ui_操作图形层->mf_DrawFun  = on_视口操作图形层绘制;
	ui_操作图形层->mf_变换修改 = on_视口操作图形层变换;
	
	ui_操作图形层->mf_开始拖拽 = on_3D视口准备_拖动;
	ui_操作图形层->mf_拖拽     = on_3D视口_拖动;
	ui_操作图形层->mf_结束拖拽 = on_3D视口_结束拖放;


	f_添加子组件(ui_三维视口);
	ui_三维视口->f_添加子组件(ui_操作图形层);
	ui_三维视口->mf_鼠标进入 = on_Widget鼠标进入;


	mf_布局Fun = on_3D视口布局;
	f_ui_3D视口绑定场景更新回调(ui_三维视口, on_3D场景视口_渲染场景);


	m_是否开启视线旋转物体 = false;
	m_旋转度 = 0.0f;

	gui_3D视口.push_back(ui_三维视口);
}

C_3D场景视口::~C_3D场景视口() {
	for (auto& it = gui_3D视口.begin(); it != gui_3D视口.end(); ++it) {
		if (*it == ui_三维视口) {
			gui_3D视口.erase(it);
			break;
		}
	}
}

void C_3D场景视口::f_旋转辅助线绘制(vec2 中心坐标, float32 角度弧度, float32 长度) {
	m_旋转缩放线绘制.f_alloc(1);

	mat3X2 lineMat;

	lineMat.row0 = 中心坐标;
	lineMat.row1.x = 长度;
	lineMat.row1.y = 0;
	lineMat.row2 = { 1, 角度弧度 };

	auto C = f_PackData4X8(S_主题颜色::uic_当前时间线);
	m_旋转缩放线绘制.f_set单色线(0, lineMat, { 1.0, C, C }, S_Widget预设图元::m_横线, 2.0);

}

void C_3D场景视口::f_关闭虚拟线绘制() {
	m_旋转缩放线绘制.f_Close();
}

void C_3D场景视口::f_设置渲染方式(uint8 id) {
	f_UI_切换3D视口渲染模式(ui_三维视口, E_物体显示模式(id));
}

void C_3D场景视口::f_渲染() {
	f_ui_3D视口渲染(ui_三维视口);
}






void f_view3d_重构状态条(C_状态条* 状态条, C_Widget* 三维视口) {
	
	std::vector<S_Props> props;
	S_Props	prop;

	switch (S_框架::g当前编辑对象类型) {
	case E_物体类型::t_网格:
		//S_Core::m_网格编辑模式.m_UI->m_部件 = nullptr;
		props.push_back(S_节点数据状态::g_网格编辑模式);
		break;
	case E_物体类型::t_骨架:
	case E_物体类型::t_骨骼:
		props.push_back(S_节点数据状态::g_骨骼编辑模式);
		props.push_back(S_框架::g_骨骼姿态编辑模式);
		
		S_节点数据状态::g_骨骼编辑模式.m_UI->m_Update = f_vecw3d_骨骼编辑模式;
		break;
	case E_物体类型::t_灯光:
		//S_Core::m_灯光编辑模式.m_UI->m_部件 = nullptr;
		props.push_back(S_节点数据状态::g_灯光编辑模式);
		break;
	default:
		break;
	}
	



	S_框架::g_变换类型开关.m_UI->m_Update = on_控制手柄切换;
	S_框架::g_变换类型开关.m_私有 = true;
	on_控制手柄切换(S_框架::g_变换类型开关);
	//for (uint8 i = 0; i < 3; ++i) f_控制手柄_变换手柄开关(E_变换(i + 1), e[i].m_Value);
	props.push_back(S_框架::g_变换类型开关);

	prop = f_alloc_NoneProp();
	props.push_back(prop);



	prop = f_alloc_EnumProp(nullptr,
		{ {L"点显示", "点阵"}, {L"线显示", "网格"}, {L"面显示", "球"}, {L"材质显示", "05_关照多维材质"}, {L"渲染", "05_关照多维材质"} },
		L"显示模式",
		2);
	prop.m_UI->m_Update = on_3D视口物体显示模式;
	props.push_back(prop);
	
	prop = f_alloc_NoneProp();
	props.push_back(prop);

	prop = f_alloc_EnumProp(nullptr,
		{ {L"显示所有", "布尔并"}, {L"独显选择", "布尔阳"}, {L"隐藏未选择", "布尔阴"} },
		L"场景物体显示方式",
		0,
		on_3D视口场景物体显示方式);
	props.push_back(prop);




	状态条->f_构建属性部件(props, 状态条);
}

void f_view3d_重构属性栏(C_属性栏* plane, std::vector<S_物体*> obs, C_Widget* 三维视口) {
	std::vector<S_Props> props;

	if (obs.size() == 1) {
		S_物体* m_Ob = obs.front();

		S_Props 位置 = f_alloc_Vec3Prop(&m_Ob->m_变换.location, L"位置");
		S_Props 旋转 = f_alloc_Vec3Prop(&m_Ob->m_变换.rotation, L"旋转");
		S_Props 缩放 = f_alloc_Vec3Prop(&m_Ob->m_变换.scale, L"缩放");

		位置.m_私有 = true;										
		旋转.m_私有 = true;										
		缩放.m_私有 = true;	

		props.push_back(位置);
		props.push_back(旋转);
		props.push_back(缩放);										
	}

	plane->f_构建属性部件(props);
}


bool f_view3d_射线选中物体(const vec3& s, const vec3& e, bool 多选物体, S_摄像机* camera) {
	f_view3d_设置激活物体焦点(false);

	if (!多选物体) S_节点数据::g_选中激活物体.clear();
	auto newObjs = f_scene_射线拾取(f_NodeCtx_get默认场景(), s, e);
	S_节点数据::g_选中激活物体.insert(S_节点数据::g_选中激活物体.end(), newObjs.begin(), newObjs.end());

	f_view3d_设置激活物体焦点(true);
	
	f_页面_更新联动工作区(E_工作区类型::e_3D视口);
	f_camera_set偏移视点(camera, f_global_get激活物体中心点());
	f_global_变换手柄到物体中心();
	return false;
}

bool f_view3d_射线选中网格元素(const vec3& s, const vec3& e, bool 多选物体, S_摄像机* camera) {
	return false;
}

bool f_view3d_射线选中骨骼元素(const vec3& s, const vec3& e, bool 多选物体, S_摄像机* camera) {
	
	if (!多选物体) {
		f_global_clear拾取物体();
	}


	std::vector<S_物体拾取信息> 新拾取的物体;
	std::vector<C_节点基类*>	物体对应节点;

	for (auto& ob : S_节点数据::g_选中激活物体) {
		auto* 骨骼 = ob->m_子物体[0];
		auto 骨骼拾取 = f_scene_射线拾取物体实例(骨骼, s, e);
		auto* 骨节 = ob->m_子物体[1];
		auto& 骨节拾取 = f_scene_射线拾取物体实例(骨节, s, e);

		f_surface_fill颜色(f_ob_fromMesh(骨骼, 0), S_节点UI主题::uic_骨骼边编辑状态, 0, -1);
		f_surface_fill颜色(f_ob_fromMesh(骨骼, 1), S_节点UI主题::uic_骨骼面编辑状态, 0, -1);
		f_surface_fill颜色(f_ob_fromMesh(骨节, 0), S_节点UI主题::uic_骨骼边编辑状态, 0, -1);
		f_surface_fill颜色(f_ob_fromMesh(骨节, 1), S_节点UI主题::uic_骨骼面编辑状态, 0, -1);

		
		S_物体拾取信息 pickup = {nullptr, 0, 1e+7};
		if (骨节拾取.实例ID >= 0) {
			if (骨骼拾取.实例ID >= 0 && 骨骼拾取.相交距离 < 骨节拾取.相交距离 ) {
				goto To_骨骼拾取;
			}
			else {
				pickup = { 骨节, uint32(骨节拾取.实例ID), 骨节拾取.相交距离 };
			}

		}else  if (骨骼拾取.实例ID >= 0) {
			To_骨骼拾取:
			pickup = { 骨骼, uint32(骨骼拾取.实例ID), 骨骼拾取.相交距离 };
		}

		if (pickup.物体) {
			
			S_物体* 对应节点物体 = nullptr;
			if (pickup.物体->m_Type == E_物体类型::t_骨架) {
				f_surface_fill颜色(f_ob_fromMesh(pickup.物体, 0), S_节点UI主题::uic_骨骼编辑焦点, pickup.实例ID, 1);
				f_surface_fill颜色(f_ob_fromMesh(pickup.物体, 1), S_节点UI主题::uic_骨骼编辑焦点, pickup.实例ID, 1);

				if (pickup.实例ID) {
					对应节点物体 = f_ob_get实例ID对象(pickup.物体, pickup.实例ID);
				}
				else {
					对应节点物体 = f_ob_from实例对象取父对象(pickup.物体);
				}
				
			}
			else if (pickup.物体->m_Type == E_物体类型::t_骨骼) {
				auto* 父对象 = f_ob_from实例对象取父对象(pickup.物体);
				f_surface_fill颜色(f_ob_fromMesh(父对象, 0), S_节点UI主题::uic_骨骼编辑焦点, pickup.实例ID, 1);
				f_surface_fill颜色(f_ob_fromMesh(父对象, 1), S_节点UI主题::uic_骨骼编辑焦点, pickup.实例ID, 1);
				//对应节点物体 = f_ob_from实例对象取父对象(pickup.物体);
				对应节点物体 = pickup.物体;
				f_prop_enum(S_节点数据状态::g_骨骼编辑模式) = E_骨骼编辑模式::e_骨头编辑模式;
			}
			else {
				//选择了骨节
				f_surface_fill颜色(f_ob_fromMesh(pickup.物体, 0), S_节点UI主题::uic_骨节编辑焦点, pickup.实例ID, 1);
				f_surface_fill颜色(f_ob_fromMesh(pickup.物体, 1), S_节点UI主题::uic_骨节编辑焦点, pickup.实例ID, 1);
				//info.物体 = f_ob_get实例ID对象(info.物体, info.实例ID);
				if (pickup.实例ID > 1) {
					对应节点物体 = f_ob_get实例ID对象(骨骼, pickup.实例ID - 1);
				}
				else {
					对应节点物体 = ob;
				}
				f_prop_enum(S_节点数据状态::g_骨骼编辑模式) = E_骨骼编辑模式::e_骨节编辑模式;
			}


			pickup.物体 = f_ob_get实例ID对象(pickup.物体, pickup.实例ID);
			新拾取的物体.push_back(pickup);

			auto nodes = f_NodeCtx_从可视物体取节点({ pickup.物体 });
			for(auto& e : nodes) 物体对应节点.push_back(e);
			
		}
	}
	
	f_global_set拾取物体(新拾取的物体, !多选物体);


	if (物体对应节点.size()) {
		f_global_set激活节点(物体对应节点);
		for (auto& n : 物体对应节点) {
			std::wcout << "物体对于节点:" << n->f_getWName() << " : " << std::endl;
			std::cout << "物体对于节点:" << n->m_TypeName << std::endl;
		}
	}
	else {
		std::cout << "没有指定物体对于节点:" << std::endl;
	}

	
	f_camera_set偏移视点(camera, f_global_get激活物体中心点());

	f_页面_更新联动工作区(E_工作区类型::e_3D视口);
	return false;
}





bool f_view3d_物体编辑模式_键盘事件(const S_键盘& ks) {
	if (ks.Keys状态[S_InputKey::e_KEY_左SHIFT] == DEF_按键状态_按下中) {
		//vec2 g鼠标起始坐标 = f_widget_取鼠标局部位置(C_Widget::g_鼠标.gPos, self);
		if (ks.Keys状态[S_InputKey::e_KEY_E] == DEF_按键状态_放开) {
			switch (f_prop_enum(S_节点数据状态::g_网格编辑模式)) {
			case 0: f_prop_enum(S_节点数据状态::g_网格编辑模式) = 1; break;
			case 1: f_prop_enum(S_节点数据状态::g_网格编辑模式) = 0; break;
			default:
				break;
			}
		}
	}

	return false;
}

bool f_view3d_骨骼编辑模式_键盘事件(C_Widget* self, const S_键盘& ks, S_UI创建环境& ctx, S_摄像机* camera) {
	if (ks.Keys状态[S_InputKey::e_KEY_左SHIFT] == DEF_按键状态_按下中) {
		//vec2 g鼠标起始坐标 = f_widget_取鼠标局部位置(C_Widget::g_鼠标.gPos, self);
		if (ks.Keys状态[S_InputKey::e_KEY_E] == DEF_按键状态_放开) {
			switch (f_prop_enum(S_节点数据状态::g_骨骼编辑模式)) {
			case 0: 
				f_prop_enum(S_节点数据状态::g_骨骼编辑模式) = 1;
				f_prop_Bool(S_节点数据状态::g_打开编辑模式) = true;
				break;
			case 1: 
				f_prop_Bool(S_节点数据状态::g_打开编辑模式) = false;
				f_prop_enum(S_节点数据状态::g_骨骼编辑模式) = 0;
				break;
			default:
				break;
			}

			f_OE_骨骼编辑模式切换(S_节点数据状态::g_骨骼编辑模式);
			//f_view3d_骨骼状态切换(f_prop_enum(S_节点数据状态::g_骨骼编辑模式).m_当前选项);
			if (S_节点数据状态::g_骨骼编辑模式.m_UI->m_Set) S_节点数据状态::g_骨骼编辑模式.m_UI->m_Set(S_节点数据状态::g_骨骼编辑模式);
		}

		return false;
	}
	
	if (f_prop_enum(S_节点数据状态::g_骨骼编辑模式)) {
		if (ks.Keys状态[S_InputKey::e_KEY_E] == DEF_按键状态_按下) {
			
			std::vector<S_物体拾取信息> 拾取物体;
			std::vector<S_物体*> obs;
			auto pickobs = f_global_get编辑拾取物体();
			for (auto& e : pickobs) {
				
				auto* 新节点 = f_节点构建_骨头节点(ctx, *S_框架::g_3D视口环境);
				auto ob = 新节点->m_NodeData->f_get虚拟体();
				if (e.物体->m_Type == E_物体类型::t_骨骼) {
					拾取物体.push_back({ ob, ob->m_实例ID, 0 });
				}
				else {
					S_物体* 新骨节 = ((S_物体*)ob->m_UserData);
					拾取物体.push_back({ 新骨节, 新骨节->m_实例ID, 0 });
					新骨节->f_set位置(((S_物体*)e.物体)->f_get位置(), 0);
				}

				
				obs.push_back(e.物体);

				std::vector<C_节点基类*> 已有要链接的节点;
				if (e.物体->m_Type == E_物体类型::t_骨骼) {
					已有要链接的节点 = f_NodeCtx_从可视物体取节点({ e.物体 });
				}
				else {
					已有要链接的节点 = f_NodeCtx_从可视物体取节点({ (S_物体*)e.物体->m_UserData });
				}

				std::vector<C_节点面板*> 上方节点面板组;
				for (auto& 当前节点 : 已有要链接的节点.front()->m_包含在多个视口的UI部件) {
					C_节点面板* 节点面板 = static_cast<C_节点面板*>(当前节点);
					if (节点面板) {
						vec2 p = {};
						p.y -= 当前节点->f_getSize().y;
						f_NodeView_设置节点面板局部添加位置(p);


					}
					上方节点面板组.push_back(节点面板);
				}

				f_NodeView_其他工作区添加面板到视口(新节点, true);
				f_NodePlane_链接节点(新节点, 1, static_cast<C_节点面板*>(上方节点面板组.front()), 1);
				
			}
			f_控制手柄_移动到选中物体中心();

			//添加骨节节点
			f_NE_骨骼编辑状态颜色设置(S_节点数据::g_选中激活物体);
			f_global_set拾取物体(拾取物体);
			
			f_OE_准备移动(self, camera);
			f_控制手柄_准备移动物体();
		}
	}

	return false;
}

void f_view3d_设置激活物体焦点(bool 激活) {
	if (激活) {
		for (auto* ob : S_节点数据::g_选中激活物体) {
			f_global_物体显示模式_打开焦点(ob, ob->m_实例ID);

			uint32 实例ID = ob->m_实例ID;
			switch (ob->m_Type) {
			case E_物体类型::t_虚拟体:
			case E_物体类型::t_区域光_方形:
			case E_物体类型::t_区域光_圆形:
			case E_物体类型::t_平行光:
			case E_物体类型::t_聚光灯:
			case E_物体类型::t_区域光:
			case E_物体类型::t_点光源:
				ob = ob->m_父物体;
			case E_物体类型::t_包:
			{
				for (uint32 i = 0; i < ob->m_DataNum; ++i) {
					S_Mesh* mesh = f_ob_fromMesh(ob, i);
					f_buf_物体变换属性_at(mesh->m_网格元素属性, 实例ID).m_Color = f_PackData4X8(S_主题颜色::uic_物体焦点颜色);
				}
			}
			}
		}
	}
	else {
		for (auto* ob : S_节点数据::g_选中激活物体) {
			f_global_物体显示模式_关闭焦点(ob, ob->m_实例ID);

			uint32 实例ID = ob->m_实例ID;
			switch (ob->m_Type) {
			case E_物体类型::t_虚拟体:
			case E_物体类型::t_区域光_方形:
			case E_物体类型::t_区域光_圆形:
			case E_物体类型::t_平行光:
			case E_物体类型::t_聚光灯:
			case E_物体类型::t_区域光:
			case E_物体类型::t_点光源:
				ob = ob->m_父物体;
			case E_物体类型::t_包: {
				for (uint32 i = 0; i < ob->m_DataNum; ++i) {
					S_Mesh* mesh = f_ob_fromMesh(ob, i);
					f_buf_物体变换属性_at(mesh->m_网格元素属性, 实例ID).m_Color = 0;
				}
			}
			}
		}
	}
	
}

/*void f_view3d_骨骼状态切换(uint8 状态) {
	switch (状态) {
	case E_骨骼编辑模式::e_物体模式: {
		f_NE_骨骼物体状态颜色设置(S_Core::g_选中激活物体);
		break;
	}
	case E_骨骼编辑模式::e_姿态模式:
	case E_骨骼编辑模式::e_编辑模式: {
		f_NE_骨骼编辑状态颜色设置(S_Core::g_选中激活物体);
		break;
	}
	default:
		break;
	}
}*/

void f_view3d_切换物体线显示() {

}








